package com.minesweeper.ui;

import com.minesweeper.data.GameData;
import com.minesweeper.data.ImagesData;
import com.minesweeper.tools.MineListener;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.util.Random;

/**
 * @author skniy
 */
public class MinePanel extends JPanel {

    /**
     * 游戏界面
     */
    private GameInterface gameInterface;
    /**
     * 所有格子
     */
    private Block[][] blocks;

    /**
     * 构造方法
     *
     * @param gameInterface
     */
    public MinePanel(GameInterface gameInterface) {
        //设置基本属性
        this.gameInterface = gameInterface;
        this.blocks = new Block[GameData.ROWS][GameData.COLS];
        this.setLayout(new GridLayout(GameData.ROWS, GameData.COLS));
        //添加格子并设置边框效果
        addBlocks();
        setBorder();
    }

    /**
     * 添加格子
     */
    private void addBlocks() {
        //鼠标监听器
        MineListener mineListener = new MineListener(blocks, gameInterface);
        //循环建立每个格子并加入面板
        for (int i = 0; i < blocks.length; i++) {
            for (int j = 0; j < blocks[i].length; j++) {
                blocks[i][j] = new Block(i, j);
                blocks[i][j].setIcon(ImagesData.ICON_BLOCK_BLANK);
                blocks[i][j].addMouseListener(mineListener);
                this.add(blocks[i][j]);
            }
        }
        //加入地雷
        addMine();
        //加入周围地雷信息
        addLocalMineCount();
    }

    /**
     * 添加边框效果
     */
    private void setBorder() {
        //设置内外边框效果并混合
        Border borderIn = BorderFactory.createLoweredBevelBorder();
        Border borderOut = BorderFactory.createEmptyBorder(5, 5, 5, 5);
        Border border = BorderFactory.createCompoundBorder(borderOut, borderIn);
        //加入边框并置背景色为灰
        this.setBorder(border);
        this.setBackground(Color.LIGHT_GRAY);
    }

    /**
     * 初始化地雷和周围地雷信息
     */
    private void addMine() {
        //地雷数目
        int mineCount = 0;
        //随机类
        Random random = new Random();
        //加入地雷
        while (mineCount < GameData.MINE_COUNT) {
            int row = random.nextInt(GameData.ROWS);
            int col = random.nextInt(GameData.COLS);
            if (!blocks[row][col].mineStatus) {
                blocks[row][col].mineStatus = true;
                mineCount++;
            }
        }
    }

    /**
     * 加入周边地雷信息
     */
    private void addLocalMineCount() {
        //偏移量，方便遍历周围八个格子
        int[][] offset = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
        //循环便利每个格子
        for (int row = 0; row < GameData.ROWS; row++) {
            for (int col = 0; col < GameData.COLS; col++) {
                int localMineCount = 0;
                for (int[] off : offset) {
                    int localRow = row + off[0];
                    int localCol = col + off[1];
                    //如果没有越界
                    if (checkBorder(localRow, localCol)) {
                        //如果是地雷
                        if (blocks[localRow][localCol].mineStatus) {
                            localMineCount++;
                        }
                    }
                }
                blocks[row][col].localMineCount = localMineCount;
            }
        }
    }

    /**
     * 检查边界
     *
     * @param row
     * @param col
     * @return
     */
    private boolean checkBorder(int row, int col) {
        return row >= 0 && row < GameData.ROWS && col >= 0 && col < GameData.COLS;
    }

    public Block[][] getBlocks() {
        return blocks;
    }

    public void setBlocks(Block[][] blocks) {
        this.blocks = blocks;
    }
}
